import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.demo.Student;

public class App {
    //这个启动类就是用来获取Bean对象的
    public static void main(String[] args) {
        //1. 得到 Spring   //context就是上下文，ApplicationContext是一个接口，不能直接实例化，此时需要
        //new一个具体的子类，这个子类的意思就是通过xml路径的配置文件来获取到的Bean对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("String-config.xml");
        //2.从Spring容器中获取到 Bean 对象
//        Student student = (Student) context.getBean("student");//根据名称获取Bean对象
        //第二种获取Bean对象的方式
//        Student student = context.getBean(Student.class);//根据类型来获取Bean对象
        /*此时我的代码就不用进行强转了，但是此时如果Spring容器中存储了一个类型的多种实例，此时使用类型来
        * 获取Bean对象就会报错*/
        //第3种方式获取Bean对象的方式
        Student student = context.getBean("student", Student.class);
        //上诉代码就是根据名称加类型来获取Bean对象 此时不用进行强转，代码更优雅~

        Student stu = context.getBean("stu", Student.class);
        System.out.println("student == stu -> " + (student == stu));//false
        //也就是说在spring容器种存储两份一样的对象，此时也不是另一个对象的引用指向原来创建的那个对象
        //而是创建了两个一样的对象
//        Student student1 = new Student();
        //3.使用Bean（非必须）
        student.sayHi();
    }
}
/*当使用ApplicationContext的时候，就是将xml中 所有 的对象存储到spring容器中*/
/*当执行到第一步的代码的时候，此时就会去自动加载所有的bean对象，就像单例模式中的饿汉模式一样*/

/*所以ApplicationContext的特征：比较费内存，一次性加载，之后读取的速度很快*/
/*而且在继承关系上BeanFactory是ApplicationContext的父类
* 而applicationContext 比 BeanFactory的功能是更多的，*/

/*总结：
* 1.创建spring项目：  a：创建一个maven项目  b：添加spring-context依赖   c：创建一个启动类
* (启动类的作用就是为后面从spring容器种获取bean对象做准备)
* 2.存储Bean对象  a：先创建Bean对象  b：通过spring配置文件（spring-config.xml）在这个文件种
* 把bean对象添加进去
* 3.读取Bean对象（这一步就是DI，就是在运行启动类的时候来动态的从Spring中获取Bean对象）DI：
* 就是在我程序运行的时候动态的将我需要的对象（依赖的对象）注入到当前的启动类中
* a：得到Spring对象（两种方式：ApplicationContext，BeanFactory）
* b：通过Spring对象 GetBean 方法获取到Bean对象（而不是new的方式），（DI操作）
* c：非必须，使用Bean对象*/
